package com.showgood.view.mediator {
	import com.adobe.serialization.json.JSON;
	import com.greensock.easing.Circ;
	import com.greensock.easing.Bounce;
	import com.greensock.TweenLite;
	import com.showgood.config.Config;
	import com.showgood.config.PopupConfig;
	import com.showgood.core.AbstractMediator;
	import com.showgood.core.NotificationDispatcher;
	import com.showgood.core.NotificationEvent;
	import com.showgood.config.SangoConst;
	import com.showgood.config.SangoEvent;
	import com.showgood.core.GameEvent;
	import com.showgood.model.CityProxy;
	import com.showgood.model.PopupStackProxy;
	import com.showgood.model.SocketProxy;
	import com.showgood.util.GameUtil;
	import com.showgood.util.Rect;
	import com.showgood.model.GameViewProxy;
	import com.showgood.model.PreloadProxy;
	import com.showgood.util.MapElem;
	import com.showgood.view.component.MarchPath;
	import com.showgood.view.component.Square;
	import com.showgood.view.component.Triangle;
	import com.showgood.vo.ArmyVO;
	import com.showgood.vo.BaseVO;
	import com.showgood.vo.CityVO;
	import com.showgood.vo.IdVO;
	import com.showgood.vo.RectVO;
	import com.showgood.vo.RemoteMessage;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import com.showgood.view.GameView;
	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.sampler.NewObjectSample;
	import flash.text.engine.BreakOpportunity;
	import flash.text.TextField;
	import flash.utils.Dictionary;
	import mx.collections.errors.CollectionViewError;
	import mx.managers.PopUpManager;
	import com.showgood.view.CityDialog;
	import org.as3commons.collections.LinkedList;
	import org.as3commons.collections.LinkedMap;
	 
	/**
	 * 
	 * @author bianpeng
	 */
	public class GameViewMediator extends AbstractMediator {
		// 可见区域的大小
		private var _center:Point = new Point();	// 中间点对应的逻辑坐标
		// 可见的城市列表
		private var _cityInView:LinkedMap = new LinkedMap();
		private var _armyInView:LinkedMap = new LinkedMap();
		
		private function get gameView():GameView {
			return viewComponent as GameView;
		}

		public function GameViewMediator(viewObject:Object) {
			super(viewObject);
			// setup events
			gameView.addEventListener(SangoEvent.EVENT_PAN_MAP_VIEW, onPanMapView);
		}
		
		override public function onRegister():void {
			sangoFacade.registerProxyByType(new CityProxy());
		}
		
		/**
		 * 这里把屏幕切割成四份, 三份去服务器端获取, 一份在客户端过滤
		 * @param	event
		 */
		private function onPanMapView(event:GameEvent):void {
			var _proxy:GameViewProxy = sangoFacade.retrieveProxyByType(GameViewProxy) as GameViewProxy;
			var _dx:int = event.data[0];
			var _dy:int = event.data[1];
			if (_dx != 0 || _dy != 0) {
				_center.offset( -_dx, -_dy);
				// 新的原点
				_proxy.queryMapByPan(_center.x - Config.SCREEN_WIDTH / 2, 
					_center.y - Config.SCREEN_HEIGHT / 2, _dx, _dy);
				_proxy.updateUserCenter(_center.x, _center.y);
			}
		}
		override protected function setupNotifactionHandler(dispatcher:NotificationDispatcher):void {
			super.setupNotifactionHandler(dispatcher);
			dispatcher.addHandler(SangoConst.FILTER_CITY_ON_SCREEN, onFilterCityOnScreen);
			dispatcher.addHandler(SangoConst.SHOW_CITY_ON_SCREEN, onShowCityOnScreen);
			dispatcher.addHandler(SangoConst.SHOW_ARMY_ON_SCREEN, onShowArmyOnScreen);
			dispatcher.addHandler(SangoConst.SHOW_HINT, onShowHint);
			dispatcher.addHandler(SangoConst.DISBAND_ARMY, onDisbandArmy);
		}
		private function onDisbandArmy(event:NotificationEvent):void {
			var vo:IdVO = event.data as IdVO;
			if (_armyInView.hasKey(vo.id)) {
				var _elem:MapElem = _armyInView.itemFor(vo.id) as MapElem;
				gameView.armyLayer.removeChild(_elem);
				_armyInView.removeKey(vo.id);
			}
		}
		/**
		 * 5秒钟的hint
		 * @param	event
		 */
		private function onShowHint(event:NotificationEvent):void {
			gameView.hint.visible = true;
			gameView.hint.alpha = 1;
			gameView.hint.text = event.data as String;
			TweenLite.to(gameView.hint, 5, { alpha: 0.3, 'onComplete': hideHint } );
		}
		private function hideHint():void {
			gameView.hint.visible = false;
		}
		/**
		 * 在地图上创建
		 * @param	_event
		 */
		private function onShowCityOnScreen(_event:NotificationEvent):void {
			var _cityList:Vector.<BaseVO> = _event.data as Vector.<BaseVO>;
			var _proxy:PreloadProxy = sangoFacade.retrieveProxyByType(PreloadProxy) as PreloadProxy;
			var _bmp:BitmapData = _proxy.getBitmapData('city_002');
			for each(var _vo:CityVO in _cityList) {
				_logger.info(JSON.encode(_vo));
				var _it:Bitmap = new Bitmap(_bmp);
				GameUtil.center(_it);
				var view:MapElem = new MapElem(_vo, _it);
				view.x = GameUtil.calc_x(_vo.x, _vo.y);
				view.y = GameUtil.calc_y(_vo.x, _vo.y);
				view.addEventListener(MouseEvent.CLICK, onCityClilck);
				gameView.cityLayer.addChild(view);
				_cityInView.add(_vo.id, view);
			}
			_logger.info('city in recieved: ' + _cityList.length);
			_logger.info('city in view: ' + _cityInView.size);
		}
		private function onShowArmyOnScreen(event:NotificationEvent):void {
			var _armyList:Vector.<BaseVO> = event.data as Vector.<BaseVO>;
			_logger.info(_armyList);
			var _proxy:PreloadProxy = sangoFacade.retrieveProxyByType(PreloadProxy) as PreloadProxy;
			var _viewclass:Class = _proxy.getClass('ViewArea');
			var _clazz:Class = _proxy.getClass('Army');
			for each(var vo:ArmyVO in _armyList) {
				var elem:MapElem = _armyInView.itemFor(vo.captain);
				if (!_armyInView.hasKey(vo.captain)) {
					var _tria:Triangle = new Triangle(100, 30);
					var _it:MovieClip = new _clazz();
					GameUtil.center(_it);
					elem = new MapElem(vo, _it, _tria);
					
					var _viewArea:MovieClip = new _viewclass();
					GameUtil.center(_viewArea);
					_viewArea.mask = _tria;
					elem.addChildAt(_viewArea, 0);
					// 默认朝南
					elem.shadow.rotation = 180 * Math.atan2(GameUtil.calc_y(0, 1), GameUtil.calc_x(0, 1)) / Math.PI;
					
					gameView.armyLayer.addChild(elem);
					elem.addEventListener(MouseEvent.CLICK, onArmyClilck);
					_armyInView.add(vo.captain, elem);
					elem.x = GameUtil.calc_x(vo.x, vo.y);
					elem.y = GameUtil.calc_y(vo.x, vo.y);
				}
				else {
					elem.vo = vo;
					var dx:Number = GameUtil.calc_x(vo.nextx, vo.nexty);
					var dy:Number = GameUtil.calc_y(vo.nextx, vo.nexty);
					var new_angle:Number = 180 * Math.atan2(dy - elem.y, dx - elem.x) / Math.PI;
					TweenLite.to(elem, vo.duration, { x: dx, y: dy } );
					
					// 动画转弯
					var angle:int = new_angle - elem.shadow.rotation;
					if (angle != 0) {
						if (angle > 180) new_angle -= 360;
						else if (angle < -180) new_angle += 360;
						TweenLite.to(elem.shadow, 1.8, { rotation : new_angle, ease:Bounce.easeOut } );
					}
				}
			}
		}
		private function onFilterCityOnScreen(_event:NotificationEvent):void {
			var _rect:Rect = _event.data as Rect;
			
			cutCityWithRect(_rect);
			cutArmyWithRect(_rect);
		}
		private function cutArmyWithRect(_rect:Rect):void {
			var _oldList:LinkedMap = _armyInView;
			var _len:int = _oldList.size;
			
			_armyInView =  new LinkedMap();
			for (var i:int = 0 ; i < _len; ++i) {
				var _elem:MapElem = _oldList.removeFirst();
				var _vo:ArmyVO = _elem.vo as ArmyVO;
				var _x:int = GameUtil.calc_x(_vo.x, _vo.y);
				var _y:int = GameUtil.calc_y(_vo.x, _vo.y);
				if (_rect.isIn(_x, _y)) {
					_armyInView.add(_vo.captain, _elem);
				}
				else {
					gameView.armyLayer.removeChild(_elem);
				}
			}
			_logger.info('city removed: ' + (_len - _cityInView.size));
			_logger.info('city in view: ' + _cityInView.size);
		}
		private function cutCityWithRect(_rect:Rect):void {
			var _oldList:LinkedMap = _cityInView;
			var _len:int = _oldList.size;
			
			_cityInView =  new LinkedMap();
			for (var i:int = 0 ; i < _len; ++i) {
				var _elem:MapElem = _oldList.removeFirst();
				var _vo:CityVO = _elem.vo as CityVO;
				var _x:int = GameUtil.calc_x(_vo.x, _vo.y);
				var _y:int = GameUtil.calc_y(_vo.x, _vo.y);
				if (_rect.isIn(_x, _y)) {
					//_cityInView.add(_elem);
					_cityInView.add(_vo.id, _elem);
				}
				else {
					gameView.cityLayer.removeChild(_elem);
				}
			}
			_logger.info('city removed: ' + (_len - _cityInView.size));
			_logger.info('city in view: ' + _cityInView.size);
		}
		/**
		 * 点击在城市上面, 这里需要区别一下select mode, 和 command mode
		 * @param	event
		 */
		private function onCityClilck(event:MouseEvent):void {
			var elem:MapElem = event.currentTarget as MapElem;
			var _vo:CityVO = elem.vo as CityVO;
			// if has a select city , we are select army march target
			var _gameViewProxy:GameViewProxy = sangoFacade.retrieveProxyByType(GameViewProxy) as GameViewProxy;
			if (_gameViewProxy.isCreateArmyMode) {
				sendNotification(SangoConst.SELECT_CITY_DISTINATION, _vo);
			}
			else {
				var _id:IdVO = new IdVO();
				_id.id = _vo.id;
				sangoFacade.socket.sendSingleVo(RemoteMessage.REMOTE_QUERY_CITY_DETAIL, _vo.id, _id);
				var _p:PopupStackProxy = sangoFacade.retrieveProxyByType(PopupStackProxy) as PopupStackProxy;
				var _dialog:CityDialog = _p.pushWindow(PopupConfig.CITY_DIALOG).center().topwindow.window as CityDialog;
				_dialog.city = _vo;
			}
		}
		private function onArmyClilck(event:MouseEvent):void {
			var elem:MapElem = event.currentTarget as MapElem;
			var _vo:ArmyVO = elem.vo as ArmyVO;
			var _gameViewProxy:GameViewProxy = sangoFacade.retrieveProxyByType(GameViewProxy) as GameViewProxy;
			if (_gameViewProxy.isCreateArmyMode) {
				sendNotification(SangoConst.SELECT_ARMY_DISTINATION, _vo);
			}
			else {
				var _id:IdVO = new IdVO();
				_id.id = _vo.captain;
				sangoFacade.socket.sendSingleVo(RemoteMessage.REMOTE_QUERY_ARMY_DETAIL, _vo.captain, _id);
				var _p:PopupStackProxy = sangoFacade.retrieveProxyByType(PopupStackProxy) as PopupStackProxy;
				// var _dialog:CityDialog = _p.pushWindow(PopupConfig.CITY_DIALOG).center().topwindow.window as CityDialog;
				// _dialog.city = _vo;
			}
		}
		/**
		 * 初始化第一次视图
		 * @param	lx
		 * @param	ly
		 */
		public function initFirstView(cx:int, cy:int):void {
			this._center.x = cx;
			this._center.y = cy;
			
			var left:int = cx - Config.SCREEN_WIDTH / 2;
			var top:int = cy - Config.SCREEN_HEIGHT / 2;
			
			gameView.mapLayer.x = -left;
			gameView.mapLayer.y = -top;
			
			var _proxy:GameViewProxy = sangoFacade.retrieveProxyByType(GameViewProxy) as GameViewProxy;
			_proxy.queryMapByRect(left, top, Config.SCREEN_WIDTH, Config.SCREEN_HEIGHT);
			_proxy.updateUserCenter(cx, cy);
		}
	}
}

